home *** CD-ROM | disk | FTP | other *** search
/ Total Network Tools 2002 / NextStepPublishing-TotalNetworkTools2002-Win95.iso / Archive / Offline Browsing / HTTrack.exe / data1.cab / Sources / src / htsbauth.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-04-28  |  11.6 KB  |  396 lines

  1. /* ------------------------------------------------------------ */
  2. /*
  3. HTTrack Website Copier, Offline Browser for Windows and Unix
  4. Copyright (C) Xavier Roche and other contributors
  5.  
  6. This program is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 2
  9. of the License, or any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  19.  
  20.  
  21. Important notes:
  22.  
  23. - We hereby ask people using this source NOT to use it in purpose of grabbing
  24. emails addresses, or collecting any other private information on persons.
  25. This would disgrace our work, and spoil the many hours we spent on it.
  26.  
  27.  
  28. Please visit our Website: http://www.httrack.com
  29. */
  30.  
  31.  
  32. /* ------------------------------------------------------------ */
  33. /* File: httrack.c subroutines:                                 */
  34. /*       basic authentication: password storage                 */
  35. /* Author: Xavier Roche                                         */
  36. /* ------------------------------------------------------------ */
  37.  
  38.  
  39. #include "htsbauth.h"
  40.  
  41. /* specific definitions */
  42. #include "htsglobal.h"
  43. #include "htslib.h"
  44. #include <stdio.h>
  45. #include <stdlib.h>
  46. #include <string.h>
  47. /* END specific definitions */
  48.  
  49. // gestion des cookie
  50. // ajoute, dans l'ordre
  51. // !=0 : erreur
  52. int cookie_add(t_cookie* cookie,char* cook_name,char* cook_value,char* domain,char* path) {
  53.   char* a=cookie->data;
  54.   char* insert;
  55.   char cook[16384];
  56.   // effacer Θventuel cookie en double
  57.   cookie_del(cookie,cook_name,domain,path);
  58.   if ((int)strlen(cook_value)>1024) return -1;                              // trop long
  59.   if ((int)strlen(cook_name)>256) return -1;                                // trop long
  60.   if ((int)strlen(domain)>256) return -1;                                   // trop long
  61.   if ((int)strlen(path)>256) return -1;                                     // trop long
  62.   if ((int)(
  63.     strlen(cookie->data)
  64.     +strlen(cook_value)
  65.     +strlen(cook_name)
  66.     +strlen(domain)
  67.     +strlen(path)
  68.     +256
  69.     ) > cookie->max_len) return -1;               // impossible d'ajouter
  70.  
  71.   insert=a;          // insΘrer ici
  72.   while (*a) {
  73.     if ( strlen(cookie_get(a,2)) <  strlen(path) )      // long. path (le + long est prioritaire)
  74.       a=cookie->data+strlen(cookie->data);    // fin
  75.     else {
  76.       a=strchr(a,'\n');     // prochain champ
  77.       if (a==NULL)
  78.         a=cookie->data+strlen(cookie->data);    // fin
  79.       else
  80.         a++;
  81.       while(*a=='\n') a++;
  82.       insert=a;          // insΘrer ici
  83.     }
  84.   }
  85.   // construction du cookie
  86.   strcpy(cook,domain);
  87.   strcat(cook,"\t");
  88.   strcat(cook,"TRUE");
  89.   strcat(cook,"\t");
  90.   strcat(cook,path);
  91.   strcat(cook,"\t");
  92.   strcat(cook,"FALSE");
  93.   strcat(cook,"\t");
  94.   strcat(cook,"1999999999");
  95.   strcat(cook,"\t");
  96.   strcat(cook,cook_name);
  97.   strcat(cook,"\t");
  98.   strcat(cook,cook_value);
  99.   strcat(cook,"\n");
  100.   if (!( ((int) strlen(cookie->data) + (int) strlen(cook)) < cookie->max_len)) return -1;      // impossible d'ajouter
  101.   cookie_insert(insert,cook);
  102. #if DEBUG_COOK
  103.   printf("add_new cookie: name=\"%s\" value=\"%s\" domain=\"%s\" path=\"%s\"\n",cook_name,cook_value,domain,path);
  104.   //printf(">>>cook: %s<<<\n",cookie->data);
  105. #endif
  106.   return 0;
  107. }
  108.  
  109. // effacer cookie si existe
  110. int cookie_del(t_cookie* cookie,char* cook_name,char* domain,char* path) {
  111.   char *a,*b;
  112.   b=cookie_find(cookie->data,cook_name,domain,path);
  113.   if (b) {
  114.     a=cookie_nextfield(b);
  115.     cookie_delete(b,(int) a - (int) b);
  116. #if DEBUG_COOK
  117.     printf("deleted old cookie: %s %s %s\n",cook_name,domain,path);
  118. #endif
  119.   }
  120.   return 0;
  121. }
  122.  
  123. // rechercher cookie α partir de la position s (par exemple s=cookie.data)
  124. // renvoie pointeur sur ligne, ou NULL si introuvable
  125. // path est alignΘ α droite et cook_name peut Ωtre vide (chercher alors tout cookie)
  126. // .doubleclick.net    TRUE    /    FALSE    1999999999    id    A
  127. char* cookie_find(char* s,char* cook_name,char* domain,char* path) {
  128.   char* a=s;
  129.   while (*a) {
  130.     int t;
  131.     if (strnotempty(cook_name)==0)
  132.       t=1;                      // accepter par dΘfaut
  133.     else
  134.       t=( strcmp(cookie_get(a,5),cook_name)==0 );     // tester si mΩme nom
  135.     if (t) {  // mΩme nom ou nom qualconque
  136.       //
  137.       char* chk_dom=cookie_get(a,0);       // domaine concernΘ par le cookie
  138.       if ((int) strlen(chk_dom) <= (int) strlen(domain)) {
  139.         if ( strcmp(chk_dom,domain+strlen(domain)-strlen(chk_dom))==0 ) {  // mΩme domaine
  140.           //
  141.           char* chk_path=cookie_get(a,2);       // chemin concernΘ par le cookie
  142.           if ((int) strlen(chk_path) <= (int) strlen(path)) {
  143.             if (strncmp(path,chk_path,strlen(chk_path))==0 ) { // mΩme chemin
  144.               return a;
  145.             }
  146.           }
  147.         }
  148.       }
  149.     }
  150.     a=cookie_nextfield(a);
  151.   }
  152.   return NULL;
  153. }
  154.  
  155. // renvoie prochain champ
  156. char* cookie_nextfield(char* a) {
  157.   char* b=a;
  158.   a=strchr(a,'\n');     // prochain champ
  159.   if (a==NULL)
  160.     a=b+strlen(b);    // fin
  161.   else
  162.     a++;
  163.   while(*a=='\n') a++;
  164.   return a;
  165. }
  166.  
  167. // lire cookies.txt
  168. // lire Θgalement (Windows seulement) les *@*.txt (cookies IE copiΘs)
  169. // !=0 : erreur
  170. int cookie_load(t_cookie* cookie,char* fpath,char* name) {
  171.   cookie->data[0]='\0';
  172.  
  173.   // Fusionner d'abord les Θventuels cookies IE
  174. #if HTS_WIN
  175.   {
  176.     WIN32_FIND_DATA find;
  177.     HANDLE h;
  178.     char  pth[MAX_PATH + 32];
  179.     strcpy(pth,fpath);
  180.     strcat(pth,"*@*.txt");
  181.     h = FindFirstFile(pth,&find);
  182.     if (h != INVALID_HANDLE_VALUE) {
  183.       do {
  184.         if (!(find.dwFileAttributes  & FILE_ATTRIBUTE_DIRECTORY ))
  185.           if (!(find.dwFileAttributes  & FILE_ATTRIBUTE_SYSTEM )) {
  186.             FILE* fp=fopen(fconcat(fpath,find.cFileName),"rb");
  187.             if (fp) {
  188.               char cook_name[256];
  189.               char cook_value[1000];
  190.               char domainpathpath[512];
  191.               //
  192.               char domain[256];           // domaine cookie (.netscape.com)
  193.               char path[256];             // chemin (/)
  194.               int cookie_merged=0;
  195.               linput(fp,cook_name,250);
  196.               if (!feof(fp)) {
  197.                 linput(fp,cook_value,250);
  198.                 if ( (!feof(fp)) && (strnotempty(cook_value)) )  {
  199.                   linput(fp,domainpathpath,500);
  200.                   if (strnotempty(domainpathpath)) {
  201.                     if (ident_url(domainpathpath,domain,path)>=0) {
  202.                       cookie_add(cookie,cook_name,cook_value,domain,path);
  203.                       cookie_merged=1;
  204.                     }
  205.                   }
  206.                 }
  207.               }
  208.               fclose(fp);
  209.               if (cookie_merged)
  210.                 remove(fconcat(fpath,find.cFileName));
  211.             }  // if fp
  212.           }
  213.       } while(FindNextFile(h,&find));
  214.       FindClose(h);
  215.     }
  216.   }
  217. #endif
  218.   
  219.   // Ensuite, cookies.txt
  220.   {
  221.     FILE* fp = fopen(fconcat(fpath,name),"rb");
  222.     if (fp) {
  223.       char line[8192];
  224.       while( (!feof(fp)) && (((int) strlen(cookie->data)) < cookie->max_len)) {
  225.         rawlinput(fp,line,8100);
  226.         if (strnotempty(line)) {
  227.           if (strlen(line)<8000) {
  228.             if (line[0]!='#') {
  229.               char domain[256];           // domaine cookie (.netscape.com)
  230.               char path[256];             // chemin (/)
  231.               char cook_name[256];        // nom cookie (MYCOOK)
  232.               char cook_value[8192];      // valeur (ID=toto,S=1234)
  233.               strcpy(domain,cookie_get(line,0));       // host
  234.               strcpy(path,cookie_get(line,2));         // path
  235.               strcpy(cook_name,cookie_get(line,5));    // name
  236.               strcpy(cook_value,cookie_get(line,6));   // value
  237. #if DEBUG_COOK
  238.               printf("%s\n",line);
  239. #endif
  240.               cookie_add(cookie,cook_name,cook_value,domain,path);
  241.             }
  242.           }
  243.         }
  244.       }
  245.       fclose(fp);
  246.       return 0;
  247.     }
  248.   }
  249.   return -1;
  250. }
  251.  
  252. // Θcrire cookies.txt
  253. // !=0 : erreur
  254. int cookie_save(t_cookie* cookie,char* name) {
  255.   if (strnotempty(cookie->data)) {
  256.     char line[8192];
  257.     FILE* fp = fopen(fconv(name),"wb");
  258.     if (fp) {
  259.       char* a=cookie->data;
  260.       fprintf(fp,"# HTTrack Website Copier Cookie File"LF"# This file format is compatible with Netscape cookies"LF);
  261.       do {
  262.         a+=binput(a,line,8000);
  263.         fprintf(fp,"%s"LF,line);
  264.       } while(strnotempty(line));
  265.       fclose(fp);
  266.       return 0;
  267.     }
  268.   } else
  269.     return 0;
  270.   return -1;
  271. }
  272.  
  273. // insertion chaine ins avant s
  274. void cookie_insert(char* s,char* ins) {
  275.   char* buff;
  276.   if (strnotempty(s)==0) {    // rien α faire, juste concat
  277.     strcat(s,ins);
  278.   } else {
  279.     buff=(char*) malloc(strlen(s)+2);
  280.     if (buff) {
  281.       strcpy(buff,s);     // copie temporaire
  282.       strcpy(s,ins);      // insΘrer
  283.       strcat(s,buff);     // copier
  284.       free(buff);
  285.     }
  286.   }
  287. }
  288. // destruction chaine dans s position pos
  289. void cookie_delete(char* s,int pos) {
  290.   char* buff;
  291.   if (strnotempty(s+pos)==0) {    // rien α faire, effacer
  292.     s[0]='\0';
  293.   } else {
  294.     buff=(char*) malloc(strlen(s+pos)+2);
  295.     if (buff) {
  296.       strcpy(buff,s+pos);     // copie temporaire
  297.       strcpy(s,buff);         // copier
  298.       free(buff);
  299.     }
  300.   }
  301. }
  302.  
  303. // renvoie champ param de la chaine cookie_base
  304. // ex: cookie_get("ceci est<tab>un<tab>exemple",1) renvoi "un"
  305. char* cookie_get(char* cookie_base,int param) {
  306.   static char buffer[8192];
  307.   //
  308.   char * limit;
  309.   while(*cookie_base=='\n') cookie_base++;
  310.   limit = strchr(cookie_base,'\n');
  311.   if (!limit) limit=cookie_base+strlen(cookie_base);
  312.   if (limit) {
  313.     if (param) {
  314.       int i;
  315.       for(i=0;i<param;i++) {
  316.         if (cookie_base) {
  317.           cookie_base=strchr(cookie_base,'\t');       // prochain tab
  318.           if (cookie_base) cookie_base++;
  319.         }
  320.       }
  321.     }
  322.     if (cookie_base) {
  323.       if ((int) cookie_base < (int) limit) {
  324.         char* a = cookie_base;
  325.         while( (*a) && (*a!='\t') && (*a!='\n')) a++;
  326.         buffer[0]='\0';
  327.         strncat(buffer,cookie_base,(int) a - (int) cookie_base);
  328.         return buffer;
  329.       } else
  330.         return "";
  331.     } else
  332.       return "";
  333.   } else
  334.     return "";
  335. }
  336. // fin cookies
  337.  
  338.  
  339.  
  340. // -- basic auth --
  341.  
  342. /* dΘclarer un rΘpertoire comme possΘdant une authentification propre */
  343. int bauth_add(t_cookie* cookie,char* adr,char* fil,char* auth) {
  344.   if (cookie) {
  345.     if (!bauth_check(cookie,adr,fil)) {       // n'existe pas dΘja
  346.       bauth_chain* chain=&cookie->auth;
  347.       char* prefix=bauth_prefix(adr,fil);
  348.       /* fin de la chaine */
  349.       while(chain->next)
  350.         chain=chain->next;
  351.       chain->next=(bauth_chain*) calloc(sizeof(bauth_chain),1);
  352.       if (chain->next) {
  353.         chain=chain->next;
  354.         chain->next=NULL;
  355.         strcpy(chain->auth,auth);
  356.         strcpy(chain->prefix,prefix);
  357.         return 1;
  358.       }
  359.     }
  360.   }
  361.   return 0;
  362. }
  363.  
  364. /* tester adr et fil, et retourner authentification si nΘcessaire */
  365. /* sinon, retourne NULL */
  366. char* bauth_check(t_cookie* cookie,char* adr,char* fil) {
  367.   if (cookie) {
  368.     bauth_chain* chain=&cookie->auth;
  369.     char* prefix=bauth_prefix(adr,fil);
  370.     while(chain) {
  371.       if (strnotempty(chain->prefix)) {
  372.         if (strncmp(prefix,chain->prefix,strlen(chain->prefix))==0) {
  373.           return chain->auth;
  374.         }
  375.       }
  376.       chain=chain->next;
  377.     }
  378.   }
  379.   return NULL;
  380. }
  381.  
  382. char* bauth_prefix(char* adr,char* fil) {
  383.   static char prefix[HTS_URLMAXSIZE*2];
  384.   char* a;
  385.   strcpy(prefix,jump_identification(adr));
  386.   strcat(prefix,fil);
  387.   a=strchr(prefix,'?');
  388.   if (a) *a='\0';
  389.   if (strchr(prefix,'/')) {
  390.     a=prefix+strlen(prefix)-1;
  391.     while(*a != '/') a--;
  392.     *(a+1)='\0';
  393.   }
  394.   return prefix;
  395. }
  396.